/**
 *    @file       timerthread.cpp
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       02/14/2014 12:32:40 AM
 *
 *    @author     Theophilus (), wangtf418@gmail.com 
 */
#include "timerthread.h"
#include "toolkit.h"
#include "server.h"


timerthread::timerthread(bf_uint32_t type, bf_uint32_t size, bf_uint32_t index, const comargs *args)
	: asynworkthread(type, size, index, args)
{
	m_cur_time = toolkit::get_unixtime();
}

timerthread::~timerthread()
{

}

bf_int_t timerthread::run()
{
	init_run();

	bf_time_t last_time = toolkit::get_unixtime();
	m_cur_time = last_time;
	message *msg = NULL;
	while(m_runflag)
	{
		m_cur_time = toolkit::get_unixtime();
		server::get()->set_time(m_cur_time);
		if (m_cur_time > last_time)
		{
			last_time = m_cur_time;
			check_timer();
		}

		msg = m_msg_queue.get();
		if (msg)
		{
			proc_msg(msg);
			delete msg;
		}
		else
		{
			toolkit::usleep_byselect(0, 10000);
		}
	}

	uninit_run();
	return BF_OK;
}


bf_int_t timerthread::proc_msg(message *msg)
{
	msghead &head = msg->get_msghead();
	switch (head.m_msgtype)
	{
		case MSG_TYPE_ADD_ITIMER:
			{
				simplemsgbody<interval_timer> *body = (simplemsgbody<interval_timer>*)msg->get_msgbody();
				if (body)
				{
					m_timer.add_timer(body->get_info());
				}
				break;
			}
		case MSG_TYPE_ADD_PTIMER:
			{
				simplemsgbody<point_timer> *body = (simplemsgbody<point_timer>*)msg->get_msgbody();
				if (body)
				{
					m_timer.add_timer(body->get_info());
				}
				break;
			}
		default:
			{
				break;
			}
	}
	return BF_OK;
}

void timerthread::check_timer()
{
	std::list<common_timer> timer_list;
	m_timer.check_interval_timer(m_cur_time, timer_list);
	std::list<common_timer>::iterator itr = timer_list.begin();
	for (; itr != timer_list.end(); itr ++)
	{
		simplemsgbody<bf_uint32_t>	 *body = new simplemsgbody<bf_uint32_t>(itr->m_timer_type);		
		send_msg(itr->m_src_thd_type, itr->m_src_thd_index, itr->m_src_tsk_id, MSG_TYPE_ITIMER_ONTIME, body);
	}

	timer_list.clear();
	bf_tm_t cur_tm;
	toolkit::sec2time(m_cur_time, cur_tm);
	m_timer.check_point_timer(cur_tm, timer_list);
	itr = timer_list.begin();
	for (; itr != timer_list.end(); itr ++)
	{
		simplemsgbody<bf_uint32_t>	 *body = new simplemsgbody<bf_uint32_t>(itr->m_timer_type);		
		send_msg(itr->m_src_thd_type, itr->m_src_thd_index, itr->m_src_tsk_id, MSG_TYPE_PTIMER_ONTIME, body);
	}
	return;
}

